<template>
    <div class="page-container">
        <div class="grid-form-container">
            <div class="operation">
                <el-button type="primary" @click="add">新增</el-button>
                <el-button type="primary" @click="edit">编辑</el-button>
                <el-popconfirm title="删除该菜单会同时删除其子菜单，是否继续？" confirmButtonText='确定' cancelButtonText='再考虑一下' @confirm="onConfirm">
                    <template #reference>
                        <el-button>删除</el-button>
                    </template>
                </el-popconfirm>
            </div>
            <div class="search">
                <el-input v-model="query.name" class="search-input-class" placeholder="菜单名称" />
                <el-button type="primary" @click="loadData">查询</el-button>
                <el-button @click="reset">重置</el-button>
            </div>
        </div>
        <div class="grid-container">
            <el-table ref="menuTable" :data="table.data" border @row-click="handleClickTableRow" @selection-change="handleSelectionChange">
                <el-table-column type="selection" width="55" />
                <el-table-column prop="name" label="菜单" width="200" />
                <el-table-column prop="pName" label="上级菜单" width="200" />
                <el-table-column prop="icon" label="图标" width="200" />
                <el-table-column prop="sortIndex" label="排序" width="80" />
                <el-table-column prop="url" label="地址" show-overflow-tooltip />
            </el-table>
        </div>
        <div class="pagination-container">
            <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="table.pagination.currentPage" :page-sizes="table.pagination.pageSizes" :page-size="table.pagination.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="table.pagination.total">
            </el-pagination>
        </div>
        <el-dialog title="菜单" v-model="showMenuDialog" width="500px" :lock-scroll="true" :close-on-click-modal="false" destroy-on-close>
            <div class="dialog-content">
                <div class="menu-form">
                    <div class="form-item">
                        <div class="label-class">菜单名称</div>
                        <div class="content-class">
                            <el-input v-model="form.name" class="form-input-class" placeholder="请输入菜单名称"></el-input>
                        </div>
                    </div>
                    <div class="form-item">
                        <div class="label-class">上级菜单</div>
                        <div class="content-class">
                            <el-input v-model="form.pName" placeholder="请输入内容" readonly class="form-input-class">
                                <template #append>
                                    <el-button type="primary" @click="showMenuTreeDialog = true">选择</el-button>
                                </template>
                            </el-input>
                        </div>
                    </div>
                    <div class="form-item">
                        <div class="label-class">菜单图标</div>
                        <div class="content-class">
                            <el-input v-model="form.icon" class="form-input-class" placeholder="请输入菜单名称"></el-input>
                        </div>
                    </div>
                    <div class="form-item">
                        <div class="label-class">菜单地址</div>
                        <div class="content-class">
                            <el-input v-model="form.url" class="form-input-class" placeholder="请输入菜单地址"></el-input>
                        </div>
                    </div>
                    <div class="form-item">
                        <div class="label-class">菜单排序</div>
                        <div class="content-class">
                            <el-input v-model="form.sortIndex" class="form-input-class" placeholder="请输入菜单地址"></el-input>
                        </div>
                    </div>
                </div>
            </div>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="showMenuDialog = false">取 消</el-button>
                    <el-button type="primary" @click="onSubmit">确 定</el-button>
                </span>
            </template>
            <el-dialog width="400px" top="20vh" title="菜单树" v-model="showMenuTreeDialog" append-to-body>
                <div class="tree-dialog-content">
                    <menu-tree :treeData="treeData" @select="treeSelected"></menu-tree>
                </div>
            </el-dialog>
        </el-dialog>
    </div>
</template>
<script>
import { ref, toRefs, reactive, onMounted } from 'vue'
import { ElNotification } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import http from '@/http.js'
import MenuTree from '@/components/sys/MenuTree.vue'
import treeUtil from '@/utils/tree.js'

export default {
    name: 'Menu',
    components: {
        MenuTree
    },
    setup() {
        const router = useRouter();
        const route = useRoute();
        const menuTable = ref(null);

        const state = reactive({
            query: {
                name: '',
            },
            table: {
                data: [],
                selected: [],
                pagination: {
                    currentPage: 1,
                    pageSizes: [10, 20, 50, 100],
                    pageSize: 10,
                    total: 0
                }
            },
            showMenuDialog: false,
            showMenuTreeDialog: false,
            form: {},
            treeData: []
        });

        const handleSelectionChange = (val) => {
            state.table.selected = val;
        }

        const handleSizeChange = (val) => {
            state.table.pagination.pageSize = val;
            loadData();
        };

        const handleCurrentChange = (val) => {
            state.table.pagination.currentPage = val;
            loadData();
        };

        const handleClickTableRow = (row) => {
            menuTable.value.clearSelection();
            menuTable.value.toggleRowSelection(row);
        }

        const loadData = () => {
            let params = {
                name: state.query.name,
                page: state.table.pagination.currentPage,
                pageSize: state.table.pagination.pageSize
            }
            http.fetchForm({
                url: '/sys/menu/queryGrid',
                data: params
            }).then((res) => {
                state.table.data = res.data.grid;
                state.table.pagination.total = res.data.total;
            });
        }

        const reset = () => {
            state.query.name = '';
            loadData();
        }

        const onSubmit = () => {
            let params = state.form;
            params['permissions'] = JSON.stringify(params.permissions);
            http.fetchJson({
                url: '/sys/menu/save',
                data: params
            }).then((res) => {
                ElNotification({
                    title: '提示',
                    message: "保存成功",
                    type: 'success'
                });
                state.showMenuDialog = false;
                loadData();
                loadTreeData();
            });
        }

        const add = () => {
            state.form = {
                id: '',
                pId: '',
                pName: '',
                name: '',
                icon: '',
                url: '',
                sortIndex: 1
            }
            state.showMenuDialog = true;
        }

        const edit = () => {
            let selected = state.table.selected;
            if (selected.length == 0) {
                ElNotification({
                    title: '提示',
                    message: "请选择要删除的菜单",
                    type: 'info'
                });
                return;
            }
            state.form = {
                id: selected[0].id,
                pId: selected[0].pId,
                pName: selected[0].pName,
                name: selected[0].name,
                icon: selected[0].icon,
                url: selected[0].url,
                sortIndex: selected[0].sortIndex
            }
            state.showMenuDialog = true;
        }

        const onConfirm = () => {
            let selected = state.table.selected;
            if (selected.length == 0) {
                ElNotification({
                    title: '提示',
                    message: "请选择要删除的菜单",
                    type: 'info'
                });
                return;
            }
            http.fetchForm({
                url: '/sys/menu/deleteById',
                method: 'post',
                data: {
                    id: selected[0].id
                }
            }).then((res) => {
                ElNotification({
                    title: '提示',
                    message: "删除成功",
                    type: 'success'
                });
                loadData();
            });
        }

        const treeSelected = (res) => {
            state.form['pId'] = res.id;
            state.form['pName'] = res.label;
            state.showMenuTreeDialog = false;
        }

        const loadTreeData = () => {
            http.fetchForm({
                url: '/sys/menu/queryAll',
                data: {}
            }).then((res) => {
                state.treeData = treeUtil.generateMenuTreeData('', res.data);
            });
        }

        // mounted
        onMounted(() => {
            loadData();
            loadTreeData();
        });

        return {
            ...toRefs(state),
            menuTable,
            handleSelectionChange,
            handleSizeChange,
            handleCurrentChange,
            handleClickTableRow,
            loadData,
            reset,
            add,
            edit,
            onSubmit,
            onConfirm,
            treeSelected
        };
    }
}
</script>
<style scoped>
.page-container {
    width: 100%;
    height: 100%;
}

.grid-form-container {
    width: 100%;
    padding: 20px 10px 10px 10px;
    display: flex;
    justify-content: space-between;
}

.search {
    display: flex;
}

.search-input-class {
    width: 180px;
    margin-right: 10px;
}

.grid-container {
    padding: 10px 10px 0 10px;
}

.pagination-container {
    padding: 10px;
}

.dialog-content {
    padding: 10px 20px;
}

.label-class {
    width: 100%;
    padding: 10px 0;
    font-size: 12px;
    color: #657180;
    font-weight: bold;
}

.content-class {
    width: 100%;
    padding: 0 0 10px 0;
}

.form-input-class {
    width: 100%;
}

.tree-dialog-content {
    padding: 10px;
    height: 400px;
    overflow: auto;
    overflow-x: hidden;
}
</style>